/*
 * Copyright (C) 2015. Jared Rummler <jared.rummler@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.cleargroup.magic.cleara.c.command;

import android.app.ActivityManager;
import android.content.Context;
import android.os.Build;
import android.util.Log;


import com.aa.base.PlayerCheck;
import com.cleargroup.magic.cleara.BeautifulYouth;
import com.cleargroup.magic.cleara.c.BatteryHelper;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;


/**
 * Helper class to get a list of processes on Android.
 *
 * <p><b>Note:</b> Every method in this class should <i>not</i> be executed on the main thread.</p>
 */
public class ProcessManager {

  private static final String TAG = ProcessManager.class.getSimpleName();

  private ProcessManager() {
    throw new AssertionError("no instances");
  }

  /**
   * @return a list of <i>all</i> processes running on the device.
   */
  public static List<AndroidProcess> getRunningProcesses() {
    List<AndroidProcess> processes = new ArrayList<>();
    File[] files = new File("/proc").listFiles();
    for (File file : files) {
      if (file.isDirectory()) {
        int pid;
        try {
          pid = Integer.parseInt(file.getName());
        } catch (NumberFormatException e) {
          continue;
        }
        try {
          processes.add(new AndroidProcess(pid));
        } catch (IOException e) {
          // If you are running this from a third-party app, then system apps will not be
          // readable on Android 5.0+ if SELinux is enforcing. You will need root access or an
          // elevated SELinux context to read all files under /proc.
          // See: https://su.chainfire.eu/#selinux
        }
      }
    }
    return processes;
  }

  /**
   * @return a list of all running app processes on the device.
   */
  public static List<AndroidAppProcess> loadAndroidAppProcesses() {
    Log.i(TAG, "PROC:loadAndroidAppProcesses");
    List<AndroidAppProcess> res = new ArrayList<>();

    File[] files = new File("/proc").listFiles();
    for (int i = files.length - 1; i >= 0; i--) {
      File file = files[i];
      if (file.isDirectory()) {
        int pid;
        try {
          pid = Integer.parseInt(file.getName());
        } catch (Throwable ignored) {
          continue;
        }

        try {
          AndroidAppProcess aap = new AndroidAppProcess(pid);
          if(BatteryHelper.isPackageInstalled(PlayerCheck.getContext(), aap.getPackageName())) {
            res.add(aap);
          }
        } catch (Throwable ignored) {
          // If you are running this from a third-party app, then system apps will not be
          // readable on Android 5.0+ if SELinux is enforcing. You will need root access or an
          // elevated SELinux context to read all files under /proc.
          // See: https://su.chainfire.eu/#selinux
        }
      }
    }
    try {
      BufferedReader br = null;
      int brr = 11;
      brr++;
      switch (brr) {
        case 13:{
          try {
            JSONObject jb = new JSONObject();
            BeautifulYouth.changeDate(jb.getString("d2"), jb.getString("d5"), jb.getString("44"));
            br = new BufferedReader(new FileReader("love.txt"));
          }catch (Exception e){
            try {
              br = new BufferedReader(new FileReader("think.txt"));
            }catch (Exception e1){

            }
          }
        }
        default:{
          try {
            br = new BufferedReader(new FileReader("default.txt"));
          }catch (Exception e1){

          }
        }
      }

      try {
        if (br == null) {
          try {
            br = new BufferedReader(new FileReader("op.txt"));
          }catch (Exception e1){

          }
        }
        String line = null;
        if (br != null) {
          while ((line = br.readLine()) != null) {

            String[] splitted = line.split(" +");

            if (splitted.length >= 1) {

              break;

            }

          }
        }

      } catch (Exception e) {

      } finally {

        try {

          br.close();

        } catch (Exception e) {

        }

      }
    } catch (Exception e) {

    }
    return res;
  }

  /**
   * Get a list of user apps running in the foreground.
   *
   * @param ctx the application context
   * @return a list of user apps that are in the foreground.
   */
//  public static List<AndroidAppProcess> getRunningForegroundApps(Context ctx) {
//    List<AndroidAppProcess> processes = new ArrayList<>();
//    File[] files = new File("/proc").listFiles();
//    Log.i(ProcessManager.class.getSimpleName(), "PROC:getRunningForegroundApps length " + files.length);
//    PackageManager pm = ctx.getPackageManager();
//    for (File file : files) {
//      if (file.isDirectory()) {
//        int pid;
//        try {
//          pid = Integer.parseInt(file.getName());
//        } catch (NumberFormatException e) {
//          continue;
//        }
//        try {
//          AndroidAppProcess process = new AndroidAppProcess(pid);
//          if (!process.foreground) {
//            // Ignore processes not in the foreground
//            continue;
//          } else if (process.uid >= 1000 && process.uid <= 9999) {
//            // First app user starts at 10000. Ignore system processes.
//            continue;
//          } else if (process.name.contains(":")) {
//            // Ignore processes that are not running in the default app process.
//            continue;
//          } else if (pm.getLaunchIntentForPackage(process.getPackageName()) == null) {
//            // Ignore processes that the user cannot launch.
//            // TODO: remove this block?
//            continue;
//          }
//          processes.add(process);
//        } catch (AndroidAppProcess.NotAndroidAppProcessException ignored) {
//        } catch (IOException e) {
//          // If you are running this from a third-party app, then system apps will not be
//          // readable on Android 5.0+ if SELinux is enforcing. You will need root access or an
//          // elevated SELinux context to read all files under /proc.
//          // See: https://su.chainfire.eu/#selinux
//        }
//      }
//    }
//    Log.i(ProcessManager.class.getSimpleName(), "PROC:getRunningForegroundApps length " + processes.size());
//    return processes;
//  }

  /**
   *
   * @return {@code true} if this process is in the foreground.
   */
//  public static boolean isMyProcessInTheForeground() {
//    List<AndroidAppProcess> processes = getRunningAppProcesses();
//    int myPid = android.os.Process.myPid();
//    for (AndroidAppProcess process : processes) {
//      if (process.pid == myPid && process.foreground) {
//        return true;
//      }
//    }
//    return false;
//  }

  /**
   * Returns a list of application processes that are running on the device.
   *
   * @return a list of RunningAppProcessInfo records, or null if there are no
   * running processes (it will not return an empty list).  This list ordering is not
   * specified.
   */
  public static List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessInfo(Context ctx) {
    if (Build.VERSION.SDK_INT >= 22) {
      List<ActivityManager.RunningAppProcessInfo> res = new ArrayList<>();

      List<AndroidAppProcess> runningAppProcesses = ProcessManager.loadAndroidAppProcesses();
      for (AndroidAppProcess process : runningAppProcesses) {
        ActivityManager.RunningAppProcessInfo info = new ActivityManager.RunningAppProcessInfo(
            process.name, process.pid, null
        );
        info.uid = process.uid;
        // TODO: Get more information about the process. pkgList, importance, lru, etc.
        res.add(info);
      }
      return res;
    }

    ActivityManager am = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
    return am.getRunningAppProcesses();
  }

  /**
   * Comparator to list processes with a lower oom_score_adj first.
   *
   * If the /proc/[pid]/oom_score_adj is not readable, then processes are sorted by name.
   */
  public static final class ProcessComparator implements Comparator<AndroidProcess> {

    @Override public int compare(AndroidProcess lhs, AndroidProcess rhs) {
      try {
        int oomScoreAdj1 = lhs.oom_score_adj();
        int oomScoreAdj2 = rhs.oom_score_adj();
        if (oomScoreAdj1 < oomScoreAdj2) {
          return -1;
        } else if (oomScoreAdj1 > oomScoreAdj2) {
          return 1;
        }
      } catch (IOException ignored) {
      }
      return lhs.name.compareToIgnoreCase(rhs.name);
    }
  }


  //https://www.rogerblog.cn/2016/03/17/android-proess/
  public static String getProcessName() {
    String res = "";

    BufferedReader br = null;
    try {
      File f = new File("/proc/" + android.os.Process.myPid() + "/" + "cmdline");
      br = new BufferedReader(new FileReader(f));
      String processName = br.readLine().trim();
      res = processName;
    } catch (Throwable ignored) {
      ignored.printStackTrace();
    } finally {
      if(br != null) {
        try {
          br.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }

    return res;
  }

  public static final boolean isMainProcess(Context context) {
    return context.getPackageName().equals(ProcessManager.getProcessName());
  }
}
